package com.zivwu.utils.device;

import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.text.TextUtils;


import androidx.annotation.IntRange;
import androidx.core.graphics.drawable.DrawableCompat;

import com.zivwu.utils.model.Size;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * todo 完善exception
 */
public class DrawableUtils {
    public static Size DEF_OUTPUT_SIZE = new Size(1920, 1080);


    /**
     * 为图片添加一层tint
     *
     * @param drawable
     * @param colorStateList
     * @return
     */
    public static Drawable tintDrawable(Drawable drawable, ColorStateList colorStateList) {
        Drawable wrappedDrawable = DrawableCompat.wrap(drawable.mutate());
        DrawableCompat.setTintList(wrappedDrawable, colorStateList);
        return wrappedDrawable;
    }


    /**
     * 测量
     *
     * @param path
     * @return
     */
    public static Size measureSize(String path) {
        if (TextUtils.isEmpty(path))
            return null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        //只会返回这个bitmap的尺寸
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        int height = options.outHeight;
        int width = options.outWidth;
        return new Size(width, height);
    }


    public static int measureSampleSize(Size bitMapSize, Size outSize) {
        int sampleSize = 1;
        if (bitMapSize == null || outSize == null)
            return sampleSize;
        int min = Math.min(bitMapSize.getHeight() / outSize.getHeight(),
                bitMapSize.getWidth() / outSize.getWidth());
        while (min > 2) {
            min /= 2;
            sampleSize *= 2;
        }
        return sampleSize;
    }


    private static Bitmap rotateBitmap(String path, Bitmap scaledBitmap) {
        int orientation = 0;

        try {
            ExifInterface exif = new ExifInterface(path);
            orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION, 0);
        } catch (IOException e) {
            e.printStackTrace();
        }

        Matrix matrix = new Matrix();
        if (ExifInterface.ORIENTATION_ROTATE_90 == orientation) {
            matrix.postRotate(90);
        } else if (ExifInterface.ORIENTATION_ROTATE_180 == orientation) {
            matrix.postRotate(180);
        } else if (ExifInterface.ORIENTATION_ROTATE_270 == orientation) {
            matrix.postRotate(270);
        }
        scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
        return scaledBitmap;
    }

    /**
     * 质量压缩
     *
     * @param bitmap
     * @param maxSize 最大输出size
     * @return
     */
    public static byte[] compressByQuality(Bitmap bitmap, long maxSize) {
        return compressByQuality(bitmap, maxSize, 80);
    }


    public static byte[] compressByQuality(Bitmap bitmap, long maxSize, @IntRange(from = 50, to = 100) int quality) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int options_ = quality;
        bitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);

        while (baos.size() > maxSize) {
            baos.reset();
            options_ = Math.max(0, options_ - 10);
            bitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);
            if (options_ <= 60)
                break;
        }
        return baos.toByteArray();
    }


    public static Bitmap compressByScale(String path) {
        return compressByScale(path, DEF_OUTPUT_SIZE);
    }

    /**
     * 尺寸压缩
     *
     * @param path
     * @param outSize
     * @return
     */
    public static Bitmap compressByScale(String path, Size outSize) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        Size bitMapSize = measureSize(path);
        if (bitMapSize == null)
            return null;
        int min = measureSampleSize(bitMapSize, outSize);
        int actualOutWidth = bitMapSize.getWidth();
        int actualOutHeight = bitMapSize.getHeight();

        if (min > 1) {
            actualOutWidth /= min;
            actualOutHeight /= min;
        }
        options.inSampleSize = min;
        options.inJustDecodeBounds = false;
        Bitmap sampleBitmap = BitmapFactory.decodeFile(path, options);

        if (sampleBitmap == null)
            return null;
        double scale = Math.min((double) actualOutHeight / (double) outSize.getHeight(),
                (double) actualOutWidth / (double) outSize.getWidth());


        Bitmap scaledBitmap = Bitmap.createScaledBitmap(sampleBitmap, (int) (actualOutWidth / scale),
                (int) (actualOutHeight / scale), true);
        if (!sampleBitmap.equals(scaledBitmap))
            sampleBitmap.recycle();

        scaledBitmap = rotateBitmap(path, scaledBitmap);

        return scaledBitmap;
    }


    public static byte[] compress(String path, int size) {
        Bitmap bitmap = compressByScale(path);
        return compressByQuality(bitmap, size);
    }


    /**
     * 压缩并放入临时路径
     *
     * @param path    输入路径
     * @param maxByte 最大尺寸
     * @return 压缩过后的image path
     * @throws IOException
     */
    public static String compressToImageFile(String path, int maxByte) throws IOException {
        File file = FileUtils.provideImageStampFile();
        FileOutputStream stream = new FileOutputStream(file);
        stream.write(compress(path, maxByte));
        stream.close();
        assert file != null;
        return file.getAbsolutePath();
    }

}
